home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Scene / Eurochart44 / Articles / The256-ByteIntro.txt < prev    next >
Text File  |  2002-03-12  |  16KB  |  590 lines

  1.  
  2. »CL6:--------------------------------------------------------------------------------
  3. »CL0:                               The 256-Byte Intro
  4. »CL6:--------------------------------------------------------------------------------
  5.  
  6.                           Written by »CL5:Dr. Doom »CL6:of »CL5:IRIS
  7.  
  8. »CL1:Boredom can be a very inspiring thing.
  9.  
  10. And so  it  was that  one  day  I  was
  11. feeling  extremely bored.  Having just
  12. (sort  of)   survived  the  exhausting
  13. trial of piecing  together an issue of
  14. the  Eurochart,  »CL8:I  was more  or  less
  15. prepared  to  swallow  my  own  tongue
  16. rather than  look at  another piece of
  17. code for a long, long time. »CL1:Protracker
  18. had pissed  me off  earlier  that  day
  19. with  its "spontaneous crash" feature,
  20. and PPaint hadn't  really appealed  to
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28. me  since  I  downgraded  to  030.  No
  29. matter  how hard  I kicked  my TV set,
  30. it'd only produce predictable American
  31. sitcoms  and  creepy  soaps.  »CL7:My music
  32. collection was as humble as ever,  and
  33. I wasn't in the mood for music anyway.
  34. »CL1:And of  course no  vodka, no  beer, no
  35. horny  nurses  knocking  on  my  door,
  36. nothing.
  37.  - What a predicament, huh?
  38.  
  39. Luckily,  I'd  recently   expanded  my
  40. collection  of  scene productions, and
  41. watching a few  of  them  sounded like
  42. the perfect  remedy  for my particular
  43. problem.   Listing   the   directories
  44. alphabetically  somehow  lead  me into
  45. the "4k Intros" directory first. Yeah,
  46. go figure.  Now, since  no  group  has
  47. ever  decided to call itself "Aaabbc",
  48. Apathy   appeared   under   my   mouse
  49. pointer. A swift  double-click led  me
  50. further down the  tree and there I was
  51. confronted  with  no  less   than  one
  52. directory. Hmm. "2k Is Too Much!", the
  53. greenish  white  shouted  at  my eyes.
  54. Well, I  guess  it is.  Twice  more  I
  55. clicked.
  56.  
  57. »CL8:Suddenly,    something    caught    my
  58. attention  and  I  snapped  out  of my
  59. boredom-induced  semitrance.»CL1:  In  this
  60. directory were  three files. A readme,
  61. a .info file, and  a third file  which
  62. had to be the  executable. »CL7:What caught
  63. my attention  was  the fact  that this
  64. third  file  was  nowhere  near  2k in
  65. size. 256  bytes was  all  it amounted
  66. to.»CL1:  My  own  non-system startup alone
  67. was  some  300  bytes  (and my  system
  68. startup about a  million  times that),
  69. and if  this  was  actually  an intro,
  70. here  was   quite  an   accomplishment
  71. staring  me   in   the  face.  Without
  72. further hesitation I doubleclicked and
  73. poof! -  »CL6:My  workbench  turned  into a
  74. starfield with the message "Zeeball of
  75. Apathy,  256  bytes"  printed  in  the
  76. corner. Wow.»CL1:
  77.  
  78. In   a   heartbeat,  coder's  instinct
  79. took   over  (yes,  there  IS  such  a
  80. thing). What  was  going  on here? Was
  81. this   an   Intuition   screen?  Nope,
  82. Amiga+M did nothing.  Surely,  Zeeball
  83. couldn't  have disabled input handling
  84. in 256 bytes  AND opened  a screen AND
  85. rendered a starfield.  No, it appeared
  86. to  be  a   system   killer.   But  so
  87. small? I quit the intro  and was  even
  88. more amazed to find  my system running
  89. perfectly.   Obviously   the    system
  90. startup  was  not  only  tiny but also
  91. safe.
  92.  
  93. »CL8:Now, I'm not usually  one  to resource
  94. other people's code, and this would be
  95. no   exception.»CL1:  However,  I  couldn't
  96. resist the temptation  to load  up the
  97. Barfly  Debugger  and  have  a  little
  98. look.   Click-click-click,   and   the
  99. DissWindow  appeared.  Looking briefly
  100. at the code,  puzzled started  to take
  101. the place of  astonished. This  was no
  102. startup  routine   at  all.  Certainly
  103. wasn't  a  decruncher,  and it  wasn't
  104. even an  icon  startup even though the
  105. intro came equipped with an icon. Odd.
  106. I turned to  the  readme file.  "Don't
  107. rename the executable!", it said.
  108.  
  109. »CL7:I renamed  the executable  (well  what
  110. did you  expect when you  specifically
  111. tell   me  not  to?).  It  crashed.  I
  112. renamed it  back. It  worked.»CL1:  I  then
  113. focused on the  suspicious presence of
  114. the  icon. I  renamed  only  the .info
  115. file. It  crashed.  Aha! Although  the
  116. icon  appeared  perfectly  normal from
  117. the workbench, a  hex dump  showed  me
  118. otherwise.  What  I  saw  was  clearly
  119. code,     strings        such       as
  120. "graphics.library",0 and  empty spaces
  121. for  variables.  I   even   found  the
  122. message   "Myslenie    to   przywilej.
  123. Gratulacje!"  which I'm guessing means
  124. something to  the effect of "Congrats,
  125. you figured it out".
  126. »CL6:
  127. Apparently   the   executable   merely
  128. loaded the actual  code hidden away in
  129. the   icon. This   was   brilliant.»CL1:  A
  130. genuine fake in the truest of spirits.
  131. Thumbs  up   to    Zeeball   who   has
  132. otherwise  not  impressed  me  so  far
  133. (yes,  arrogance   is   a   registered
  134. trademark of the IRIS  Corporation, in
  135. case you're wondering).
  136.  
  137. »CL8:Now, most coders would have merely sat
  138. back, smiled  and  turned  on the next
  139. intro.»CL1:  But  not  this  one. For  some
  140. reason I  was  suddenly  determined to
  141. prove that this could  be done without
  142. faking. My mind  shifted into sideways
  143. and I loaded  my assembler, completely
  144. forgetting the pain  and the horror it
  145. had inflicted upon  me during my weeks
  146. of  setting  up  the  Eurochart.  This
  147. looked like a job for...
  148.  
  149. »CL8:     HOW TO CODE A 256-BYTE INTRO
  150.  
  151. »CL1:The  first  step  I took was scrapping
  152. the traditional startupcode.  Even  if
  153. madly   size-optimized,   it  wouldn't
  154. leave  any room  for an effect,  or at
  155. least  not  enough  for a starfield. »CL7:I
  156. wanted it to  open a screen and return
  157. to the system screen afterwards. Since
  158. no one  would  watch  a  starfield for
  159. more  than  a few seconds,»CL1:  I  figured
  160. multitasking  could  be  left  on with
  161. relative safety. It would just have to
  162. give me a planar display to work with.
  163.  
  164. So I needed to  open  grapics.library,
  165. or  at  least  find  it  in  memory in
  166. order   to   read   the  pointers   to
  167. the  active  view  and copperlist,  as
  168. well as call LoadView(null) to  safely
  169. reset  the  display.  The  traditional
  170. approach, and  the  one  taught in all
  171. coders' dogma, is to open  the library
  172. through OpenLibrary() with  a  pointer
  173. to the string "graphics.library". This
  174. alone would cost me 36 bytes. No way!
  175.  
  176.  
  177. »CL8:Long ago,  bad  coders  opted  to find
  178. exec.library and  then  traverse   the
  179. linked   list    of     libraries    a
  180. predetermined number of steps and then
  181. assume  that they'd  found the library
  182. they  were  looking  for. »CL1:  This   was
  183. possible  for  e.g.  graphics.library,
  184. because ROM libraries are always open.
  185. I decided  to  explore this. It turned
  186. out that  graphics.library was library
  187. #44 on my computer. Nice, but, just as
  188. I'd   thought  a  simple 10-byte  loop
  189. function    might    lead     me    to
  190. graphics.library,  a  reboot  later it
  191. had moved to position 35. Obviously  I
  192. would never know  where to find it. At
  193. least   not   without   comparing  the
  194. library  name  to  a  string, but that
  195. would  be  at  least  as  big  as  the
  196. traditional approach. Curses!
  197.  
  198. Then  inspiration struck (as it  often
  199. does  when  you're  a genius). I would
  200. make a compare function which compared
  201. values  derived  from  strings  rather
  202. than  strings. This  way  I would only           »PIC:3.iff»
  203. have  to  save  the   derivative   for
  204. "graphics.library",0  and  I  would be
  205. able to  find  the  right library with
  206. reasonable  certainty.  This is what I
  207. came up with:
  208.  
  209.  
  210. ; find something that looks a bit like
  211. ; graphics.library (execbase is in a6)
  212.  
  213. »CL7:.loop           move.l  4(a6),a6
  214. »CL7:                move.l  10(a6),a0
  215. »CL7:                move.l  (a0)+,d0                   »CL8:; string'
  216. »CL7:                add.l   (a0)+,d0
  217. »CL7:                add.l   (a0),d0
  218. »CL7:                cmp.l   #"grap"+"hics"+".lib",d0   »CL8:; keep the faith
  219. »CL7:                bne.b   .loop
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241. »CL1:Now     the    odds     of     finding
  242. graphics.library were in my favour and
  243. this  only  cost me  22 bytes.  I  was
  244. pretty  pleased,  although    I  still
  245. insist such  genius should be rewarded
  246. more  handsomely.   Life   is   cruel.
  247.  
  248. The startup routine  was next. I would
  249. need  to  save  the  active  view in a
  250. register,  call  LoadView(null) (which
  251. was  no  problem  now),  then set up a
  252. lowres display of some sort. »CL8:I decided
  253. to  set   up    everything    from   a
  254. copperlist,    since   I'd   need   to
  255. install  one  anyway  as the null-view
  256. copperlist continuously  disabled  all
  257. display DMA.»CL1:  But  where  to  put  the
  258. copperlist... a different  section was
  259. out of the question since the presence
  260. of more  section  descriptors  in  the
  261. executable  was  not  what  I  needed.
  262. Moreover, this  would  also  involve a
  263. relocation,  and  a  relocation  table
  264. would add  about  40 bytes, even  with
  265. only one entry. So there could only be
  266. one section,  and  it would have to be
  267. in chip memory, which is usually not a
  268. good place to put your code, but then,
  269. it was  just  a  starfield. My startup
  270. routine eventually  looked  like this:
  271.  
  272. »PIC:4.iff»             »PIC:4.iff»             »PIC:4.iff»
  273.  
  274.  
  275.  
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282. »CL7:section code,code_c
  283.  
  284. »CL7:                .
  285. »CL7:                . (graphics.library to a6)
  286. »CL7:                .
  287.  
  288. »CL7:                move.l  $22(a6),d4         »CL8:; save view
  289.  
  290. »CL7:                sub.l   a1,a1              »CL8:; loadview(null)
  291. »CL7:                jsr     -222(a6)
  292.  
  293. »CL7:                lea     copper(pc),a0      »CL8:; install copperlist
  294. »CL7:                move.l  a0,$080(a5)        »CL8:; a5 = $dff000 somehow
  295.  
  296. »CL7:                .
  297. »CL7:                . (avoiding d4 here)
  298. »CL7:                .
  299.  
  300. »CL7:                move.l  d4,a1             »CL8: ; reload view
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321. »CL7:                jsr     -222(a6)
  322. »CL7:                move.l  $26(a6),$080(a5)   »CL8:; restore copperlist
  323.  
  324. »CL7:                rts                        »CL8:; the end
  325.  
  326. »CL7:;   bonzai copperlist
  327.  
  328. »CL7:copper          dc.w    $0100,$1200        »CL8:; 1 plane, colorburst
  329. »CL7:                dc.w    $0180,$0424        »CL8:; palette (purple and
  330. »CL7:                dc.w    $0182,$008f        »CL8:;   cyan, naturally)
  331. »CL7:                dc.l    -2
  332.  
  333. »CL1:I was able to reduce the copperlist to
  334. only  setting  BPLCON0 and colour regs
  335. 0 and 1,  because  LoadView(null)  had
  336. initialised  everything  else  for me.
  337. Only  thing  missing   was   disabling
  338. sprite DMA, so sprites did flicker for
  339. the first  second the intro ran, but I
  340. left that  for  later, not knowing  if
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353. »CL1:there'd be room for it.
  354. The next step was to set up a bitplane
  355. where  I  might render my starfield. I
  356. had to  allocate   this   memory  with
  357. exec.library  to  avoid  those   nasty
  358. relocations.
  359.  
  360.  
  361.  
  362. »CL7:;   allocate chipmem space
  363.  
  364. »CL7:                move.l  4.w,a6
  365. »CL7:                moveq   #10240>>8,d0       »CL8:; give me 8000 bytes
  366. »CL7:                lsl.l   #8,d0              »CL8:; and some room to play
  367. »CL7:                moveq   #3,d1
  368. »CL7:                jsr     -198(a6)           »CL8:; allocmem()
  369. »CL7:                move.l  d0,a2              »CL8:; never fails i guess
  370.                                                  »PIC:4.iff»
  371. »CL1:Now with my bitplane safely (?) in A2,
  372. I was ready to play.  At first I tried
  373. to use the startup code as a data area
  374. for my  star  coordinates, but  it was
  375. nowhere near big  nor random enough to
  376. give    a    good    result.    So   I
  377. initialized  a  table  in my allocated
  378. memory area instead.
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402. »CL7:;   initialize stars
  403.  
  404. »CL7:                moveq.l #-79,d0            »CL8:; random number seed
  405. »CL7:                lea     8192(a2),a0
  406. »CL7:                move.w  #128*3-1,d7
  407. »CL7:.initloop       ror.l   d0,d0              »CL8:; get random number
  408. »CL7:                addq.l  #7,d0
  409. »CL7:                move.w  d0,(a0)+
  410. »CL7:                dbra    d7,.initloop
  411.  
  412. »CL1:128  stars  was  the  most I could use
  413. without  needing  a  move.w   for  the
  414. second  loop  counter. I  was  worried
  415. this would take  too much space but it
  416. had to look  good as well  as be tiny.
  417. The   main    loop    required    some
  418. consideration, as it  was the  largest
  419. part  of  the code. It  would  need to
  420. wait   for   the   vertical   blanking
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431. »CL1:
  432. interval, clear the screen, render and
  433. move the stars, test for a mouse click
  434. and loop if none occurred.
  435.  
  436. Checking  the vertical  beam  position
  437. turned   out    to    be    the   best
  438. (i.e. smallest) way to time the effect
  439.  
  440.  
  441.  
  442. »CL7:.mainloop
  443. »CL7:                .
  444. »CL7:                .
  445.  
  446. »CL7:                cmp.w  #$12f,5(a5)         »CL8:; wait for end-of-diw
  447. »CL7:                bne.b  .mainloop
  448. »CL7:                
  449.  
  450. »CL1:This left me with some time to  render
  451. before   anything  would   be   shown.
  452. Perfect.  Then  for  setting  up   and
  453. clearing  the   bitplane,   obviously:
  454.  
  455. »CL7:                move.l  a2,$0e0(a5)        »CL8:; set bitplane pointer
  456.  
  457. »CL7:                move.l  a2,a0              »CL8:; clear bitplane
  458. »CL7:                move.w  #8192/4-1,d7
  459. »CL7:.clearloop      clr.l   (a0)+
  460. »CL7:                dbra    d7,.clearloop
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481. »CL1:All  that   was  left  now   was   the
  482. starfield.  A  bit  of linear algebra,
  483. half  a  cigarette  and  one   cup  of
  484. coffee later  I  was  left with this:
  485.  
  486. »CL7:                moveq   #128-1,d6
  487. »CL7:.loopstar
  488. »CL7:                movem.w (a0)+,d0-d2   »CL8:     ; load (x,y,z) and extend
  489. »CL7:                subq.b  #7,-2(a0)     »CL8:     ; old z :- 7
  490. »CL7:                bcs.b   .skipstar     »CL8:     ; if carry, then z could
  491.                                            »CL8:;   be zero, so skip to
  492.                                            »CL8:;   avoid divide-by-zero
  493. »CL7:                lsr.w   #7,d2         »CL8:     ; force positive and
  494.                                            »CL8:;   adjust perspective
  495. »CL7:                divs.w  d2,d0             »CL8: ; do perspective thing
  496. »CL7:                divs.w  d2,d1
  497.  
  498. »CL7:                add.w   #160,d0            »CL8:; center x and clip
  499. »CL7:                cmp.w   #320,d0
  500. »CL7:                bhs.b   .skipstar
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522. »CL7:                add.w   #100,d1            »CL8:; center y and clip
  523. »CL7:                cmp.w   #200,d1            »CL8:; i don't think there's
  524. »CL7:                bhs.b   .skipstar          »CL8:;   a smaller way to do
  525. »CL7:                                           »CL8:;   this, really
  526. »CL7:                muls.w  #40,d1             »CL8:; plot point
  527. »CL7:                moveq   #-$80,d2
  528. »CL7:                ror.b   d0,d2
  529. »CL7:                lsr.w   #3,d0
  530. »CL7:                add.w   d0,d1
  531. »CL7:                or.b    d2,(a2,d1.w)
  532. »CL7:.skipstar
  533. »CL7:                dbra    d6,.loopstar
  534.  
  535. »CL7:                btst.b  #2,$016(a5)        »CL8:; test for rmb because
  536. »CL7:                bne.b   .mainloop          »CL8:;   lmb is in $bfexxx
  537. »CL7:                                           »CL8:;   and $dffxxx is in a5
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561. »CL1:After making  sure it  really  worked,
  562. I assembled  the  thing  and saved the
  563. executable. I  had done it! 240 bytes,
  564. which  was  enough  to let  me fix the
  565. sprite   flicker   problem    with  an
  566. additional copper instruction and even
  567. insert a couple of NOPs in the code to
  568. show off.
  569.  
  570. »CL8:I'm feeling  somewhat proud  of myself            »PIC:3.iff»
  571. now. I  know   this    is    a   small
  572. accomplishment,»CL1:  and   after  all,   I
  573. didn't manage to print any text on the
  574. screen (and the starfield  lacks depth
  575. shading and so on), but I  did write a
  576. "complete" intro in just 256  bytes, a
  577. thing that another  coder  had to fake
  578. but I  could  do  for  real.  I  think
  579. that's neat.  Now of  course  I'll  go
  580. back to  being  bored.  I  don't  dare
  581. watch  another  4k  intro.  Besides, I 
  582. think I'll leave those to the ones who
  583. can't  be  bothered  to  size-optimize
  584. their code.
  585.  
  586. (»CL7:You   can   find    the   uncommented
  587. sourcecode along  with the  executable
  588. somewhere  in  this Eurochart archive,
  589. probably   the    bonus    directory.»CL1:)
  590.